package org.spring.bean.factory;

import com.sun.istack.internal.Nullable;
import org.spring.bean.exceptions.BeansException;
import org.spring.bean.factory.config.ConfigurableBeanFactory;

import java.util.Map;

/**
 * 对{@link BeanFactory}接口的扩展，以由bean工厂实现，这些bean工厂可以枚举它们的所有bean实例，而不是按照客户机的请求逐个进行bean查找。
 * 预加载所有bean定义的BeanFactory实现(例如基于xml的工厂)可以实现这个接口。
 * <p>
 * 如果这是一个{@link HierarchicalBeanFactory}，则返回值将<i>而不是<i>考虑到任何BeanFactory层次结构，但将只与当前工厂中定义的bean相关。
 * 使用{@link BeanFactoryUtils}帮助类也可以考虑祖先工厂中的bean。
 * <p>
 * 这个接口中的方法将只考虑这个工厂的bean定义。它们会忽略任何通过其他方式注册的单例bean，
 * 比如{@link ConfigurableBeanFactory}的{@link ConfigurableBeanFactory#registerSingleton}方法，
 * 除了{@code getBeanNamesForType}和{@code getBeansOfType}，它们也会检查手动注册的单例。
 * 当然，BeanFactory的{@code getBean}也允许对这种特殊bean的透明访问。
 * 然而，在典型的场景中，所有bean都将由外部beanDefined定义，因此大多数应用程序不需要担心这种区别。
 * <p>
 * 注意:<b>除{@code getBeanDefinitionCount}和{@code containsBeanDefinition}外，此接口中的方法不是为频繁调用而设计的。实现可能会很慢。
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @see HierarchicalBeanFactory
 * @see BeanFactoryUtils
 * @since 16 April 2001
 */
public interface ListableBeanFactory extends BeanFactory {

    /**
     * 返回工厂中定义的bean的数量。
     * <p>
     * 不考虑该工厂可能参与的任何层次结构，并忽略任何已通过bean定义以外的方式注册的单例bean。
     *
     * @return 工厂中定义的bean的数量
     */
    int getBeanDefinitionCount();

    /**
     * 返回该工厂中定义的所有bean的名称。
     * <p>
     * 不考虑该工厂可能参与的任何层次结构，并忽略任何已通过bean定义以外的方式注册的单例bean。
     *
     * @return 此工厂中定义的所有bean的名称，如果没有定义则为空数组
     */
    String[] getBeanDefinitionNames();

    /**
     * 检查此bean工厂是否包含具有给定名称的bean定义。
     * <p>
     * 不考虑该工厂可能参与的任何层次结构，并忽略任何已通过bean定义以外的方式注册的单例bean。
     *
     * @param beanName 要查找的bean的名称
     *
     * @return 如果此bean工厂包含具有给定名称的bean定义
     *
     * @see #containsBean
     */
    boolean containsBeanDefinition(String beanName);

    /**
     * 返回与给定类型(包括子类)匹配的bean名称，这可以从bean定义或FactoryBeans中{@code getObjectType}的值来判断。
     * <p>
     * 注意:此方法只自省顶级bean。<b>它<i>不<i>检查可能匹配指定类型的嵌套bean。
     * <p>
     * 不考虑由FactoryBean创建的对象，这意味着将初始化FactoryBean。如果FactoryBean创建的对象不匹配，原始的FactoryBean本身将与类型匹配。
     * <p>
     * 不考虑该工厂可能参与的任何层次结构。使用BeanFactoryUtils' {@code beanNamesForTypeIncludingAncestors}也可以在祖先工厂中包含bean。
     * <p>
     * 注意:<i>和<i>是否忽略了通过bean定义以外的其他方式注册的单例bean。
     * <p>
     * 这个版本的{@code getBeanNamesForType}匹配所有类型的bean，无论是单例bean、原型bean还是工厂bean。
     * 在大多数实现中，结果将与{@code getBeanNamesForType(type, true, true)}相同。
     * <p>
     * 这个方法返回的Bean名应该尽可能地按照后端配置中定义<i>的顺序返回Bean名<i>。
     *
     * @param type 要匹配的类或接口，或者用于所有bean名的{@code null}
     *
     * @return 匹配给定对象类型(包括子类)的bean(或FactoryBeans创建的对象)的名称，如果没有则为空数组
     *
     * @see FactoryBean#getObjectType
     * @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, Class)
     */
    String[] getBeanNamesForType(@Nullable Class<?> type);

    /**
     * 返回与给定类型(包括子类)匹配的bean名称，这可以从bean定义或FactoryBeans中{@code getObjectType}的值来判断。
     * <p>
     * 注意:此方法只自省顶级bean。<b>它<i>不<i>检查可能匹配指定类型的嵌套bean。
     * <p>
     * 如果设置了“allowEagerInit”标志(这意味着将初始化FactoryBean)，则不考虑FactoryBean创建的对象。
     * 如果FactoryBean创建的对象不匹配，原始的FactoryBean本身将与类型匹配。
     * 如果没有设置“allowEagerInit”，则只检查原始的FactoryBean(不需要初始化每个FactoryBean)。
     * <p>
     * 不考虑该工厂可能参与的任何层次结构。使用BeanFactoryUtils' {@code beanNamesForTypeIncludingAncestors}也可以在祖先工厂中包含bean。
     * <p>
     * 注意:<i>和<i>是否忽略了通过bean定义以外的其他方式注册的单例bean。
     * <p>
     * 这个方法返回的Bean名应该尽可能地按照后端配置中定义<i>的顺序返回Bean名<i>。
     *
     * @param type                 要匹配的类或接口，或者用于所有bean名的{@code null}
     * @param includeNonSingletons 是否也包括原型bean或作用域bean，还是只包括单例bean(也适用于factorybean)
     * @param allowEagerInit       是否初始化<i>lazy-init singleton <i>和<i>对象，
     *                             该对象由FactoryBeans<i>(或由带有"factory-bean"引用的工厂方法)创建，用于类型检查。
     *                             注意，FactoryBean需要提前初始化，以确定它们的类型:因此请注意，为该标志传入"true"将初始化FactoryBean和"factory-bean"引用。
     *
     * @return 匹配给定对象类型(包括子类)的bean(或FactoryBeans创建的对象)的名称，如果没有则为空数组
     *
     * @see FactoryBean#getObjectType
     * @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean)
     */
    String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);

    /**
     * 根据bean定义或FactoryBeans中{@code getObjectType}的值，返回与给定对象类型(包括子类)匹配的bean实例。
     * <p>
     * 注意:此方法只自省顶级bean。<b>它<i>不<i>检查可能匹配指定类型的嵌套bean。
     * <p>
     * 不考虑由FactoryBean创建的对象，这意味着将初始化FactoryBean。
     * 如果FactoryBean创建的对象不匹配，原始的FactoryBean本身将与类型匹配。
     * <p>
     * 不考虑该工厂可能参与的任何层次结构。
     * 使用BeanFactoryUtils' {@code beansoftypeincluing祖先}也可以在祖先工厂中包含bean。
     * <p>
     * 注意:<i>和<i>是否忽略了通过bean定义以外的其他方式注册的单例bean。
     * <p>
     * 这个版本的getBeansOfType匹配所有类型的bean，无论是单例bean、原型bean还是工厂bean。
     * 在大多数实现中，结果将与{@code getBeansOfType(type, true, true)}相同。
     * <p>
     * 此方法返回的Map应尽可能按照后端配置中定义<i>的顺序始终返回bean名称和相应的bean实例<i>。
     *
     * @param type 要匹配的类或接口，或者所有具体bean的{@code null}
     *
     * @return 一个带有匹配bean的Map，包含bean名作为键，对应的bean实例作为值
     *
     * @throws BeansException 如果不能创建一个bean
     * @see FactoryBean#getObjectType
     * @see BeanFactoryUtils#beansOfTypeIncludingAncestors(ListableBeanFactory, Class)
     * @since 1.1.2
     */
    <T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;

    /**
     * 根据bean定义或FactoryBeans中{@code getObjectType}的值，返回与给定对象类型(包括子类)匹配的bean实例。
     * <p>
     * 注意:此方法只自省顶级bean。<b>它<i>不<i>检查可能匹配指定类型的嵌套bean。
     * <p>
     * 如果设置了“allowEagerInit”标志(这意味着将初始化FactoryBean)，则不考虑FactoryBean创建的对象。
     * 如果FactoryBean创建的对象不匹配，原始的FactoryBean本身将与类型匹配。
     * 如果没有设置“allowEagerInit”，则只检查原始的FactoryBean(不需要初始化每个FactoryBean)。
     * <p>
     * 不考虑该工厂可能参与的任何层次结构。使用BeanFactoryUtils' {@code beansoftypeincluing祖先}也可以在祖先工厂中包含bean。
     * <p>
     * 注意:<i>和<i>是否忽略了通过bean定义以外的其他方式注册的单例bean。
     * <p>
     * 此方法返回的Map应尽可能按照后端配置中定义<i>的顺序始终返回bean名称和相应的bean实例<i>。
     *
     * @param type                 要匹配的类或接口，或者所有具体bean的{@code null}
     * @param includeNonSingletons 是否也包括原型bean或作用域bean，还是只包括单例bean(也适用于FactoryBean)
     * @param allowEagerInit       是否初始化<i>lazy-init singleton <i>和<i>对象，
     *                             该对象由FactoryBeans<i>(或由带有"factory-bean"引用的工厂方法)创建，用于类型检查。
     *                             注意，FactoryBean 需要提前初始化，以确定它们的类型:因此请注意，
     *                             为该标志传入"true"将初始化 FactoryBean 和"factory-bean"引用。
     *
     * @return 一个带有匹配bean的Map，包含bean名作为键，对应的bean实例作为值
     *
     * @throws BeansException 如果不能创建一个bean
     * @see FactoryBean#getObjectType
     * @see BeanFactoryUtils#beansOfTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean)
     */
    <T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException;

}
